using System;
using System.Collections.Generic;
using System.Text;

namespace Crank.Core
{
    public static class Enumerables
    {
        public static string Join<T>(IEnumerable<T> collection, string separator)
        {
            IEnumerator<T> enumerator = collection.GetEnumerator();
            StringBuilder sb = new StringBuilder();
            if (enumerator.MoveNext())
            {
                while (true)
                {
                    sb.Append(enumerator.Current.ToString());
                    if (!enumerator.MoveNext())
                        break;
                    sb.Append(separator);
                }
            }
            return sb.ToString();
        }

        public static IEnumerable<U> Collect<T, U>(IEnumerable<T> items, Converter<T, U> converter)
        {
            foreach (T item in items)
                yield return converter(item);
        }

        public static bool IsIn<T>(T itemToLookFor, params T[] itemsToCheck) where T : IComparable<T>
        {
            return IsIn<T>(itemToLookFor, itemsToCheck as IEnumerable<T>);
        }

        public static bool IsIn<T>(T itemToLookFor, IEnumerable<T> itemsToCheck) where T : IComparable<T>
        {
            foreach (T item in itemsToCheck)
            {
                if (item.CompareTo(itemToLookFor) == 0)
                    return true;
            }
            return false;
        }

        public static void Each<T>(IEnumerable<T> collection, Action<T> action)
        {
            foreach (T item in collection)
            {
                action(item);
            }
        }

        public static IEnumerable<T> Unique<T>(IEnumerable<T> items)
        {
            List<T> visited = new List<T>();
            foreach (T item in items)
            {
                if (!visited.Contains(item))
                {
                    visited.Add(item);
                    yield return item;
                }
            }
        }

        public static IEnumerable<T> Filter<T>(IEnumerable<T> items, Predicate<T> filter)
        {
            foreach (T item in items)
            {
                if (filter(item))
                    yield return item;
            }
        }
    }
}
